package com.bijava.config;

import com.bijava.annotation.ElasticJob;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.lite.api.listener.ElasticJobListener;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Iterator;
import java.util.Map;

@Configuration
public class ElasticJobConfig {
    @Resource
    private ApplicationContext applicationContext;
    @Resource
    private ZookeeperRegistryCenter zookeeperRegistryCenter;

    /**
     * 配置任务监听器
     */
    @Bean
    public ElasticJobListener elasticJobListener() {
        return new TaskJobListener();
    }

    /**
     * 初始化配置任务
     */
    @PostConstruct
    public void initTaskJob() throws Exception {
        Map<String, SimpleJob> jobMap = this.applicationContext.getBeansOfType(SimpleJob.class);
        Iterator iterator = jobMap.entrySet().iterator();
        while (iterator.hasNext()) {
            // 自定义注解管理
            Map.Entry<String, SimpleJob> entry = (Map.Entry)iterator.next();
            SimpleJob simpleJob = entry.getValue();
            ElasticJob taskJobSign = AnnotationUtils.findAnnotation(simpleJob.getClass(), ElasticJob.class);
            if (taskJobSign != null){
                String jobName = taskJobSign.jobName();
                String jobCron = taskJobSign.jobCron();
                //任务名称或者任务执行规则为空，则提示错误信息
                if(StringUtils.isEmpty(jobName) || StringUtils.isEmpty(jobCron)){
                    throw new Exception("TaskJobSign注解参数错误：jobName或jobCron不能为空");
                }

                int shardCount = taskJobSign.shardCount();
                String shardItem = taskJobSign.shardItem();
                //如果分片数大于1但是没有设置分片规则，则提示错误信息
                if (shardCount > 1 && StringUtils.isEmpty(shardItem)){
                    throw new Exception("TaskJobSign注解参数错误：分片数大于1时，需要设置分片规则");
                }

                // 生成配置
                JobCoreConfiguration jobCoreConfiguration = JobCoreConfiguration
                        .newBuilder(jobName, jobCron, shardCount)
                        .shardingItemParameters(shardItem)
                        .jobParameter(jobName)
                        .description("作业描述")
                        .build();

                SimpleJobConfiguration simpleJobConfiguration = new SimpleJobConfiguration(
                        jobCoreConfiguration, simpleJob.getClass().getCanonicalName());

                //overwrite-本地配置是否可覆盖注册中心配置
                //disabled-作业是否禁止启动,可用于部署作业时，先禁止启动，部署结束后统一启动
                //作业监控端口,建议配置作业监控端口, 方便开发者dump作业信息。使用方法: echo “dump” | nc 127.0.0.1 9888
                LiteJobConfiguration liteJobConfiguration = LiteJobConfiguration
                        .newBuilder(simpleJobConfiguration)
                        .monitorPort(9888)
                        .overwrite(true)
                        .disabled(false)
                        .build();

                //添加监听
                TaskJobListener taskJobListener = new TaskJobListener();
                // 初始化任务
                SpringJobScheduler jobScheduler = new SpringJobScheduler(
                                                simpleJob, zookeeperRegistryCenter,
                                                liteJobConfiguration, taskJobListener);
                jobScheduler.init();
            }
        }
    }
}